home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / video / zapem-0.000 / zapem-0 / zapem / main.cc < prev    next >
C/C++ Source or Header  |  1995-06-06  |  15KB  |  678 lines

  1. /*    Copyright Alex Hornby 1994/1995. All rights reserved.
  2.      See file README for details
  3. */
  4. extern "C"{
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <vga.h>
  8. #include <vgakeyboard.h>
  9. #include <stdio.h>
  10. #include <fcntl.h>
  11. #include <unistd.h>
  12. #include "btypes.h"
  13. #include "gamelib.h"
  14. #include "screendefs.h"
  15. #include "soundIt.h"
  16. #include "alopen.h"
  17. }
  18.  
  19. // Include header files. Ordering does matter as my SE tutor says that modules
  20. // should not include things without you knowing. ( speeds up compile times as 
  21. // well :)
  22.  
  23. #include "rnd.h"
  24. #include "effects.h"
  25. #include <iostream.h>
  26. #include <string.h>
  27. #include "palette.h"
  28. #include "gif.h"
  29. #include "asmblock.h"
  30. #include "sprite.h"
  31. #include "soul.h"
  32. #include "entity.h"
  33. #include "weapon.h"
  34. #include "control.h"
  35. #include "block.h"
  36. #include "menu.h"
  37. #include "slots.h"
  38. #include "player.h"
  39. #include "display.h"
  40.  
  41. // Weapon includes
  42. #include "projectile.h"
  43. #include "popgun.h"
  44.  
  45. #include "font.h"
  46. #include "starfield.h"
  47.  
  48. // Control includes
  49. #ifdef JOYSTICK
  50. #include "Joystick.h"
  51. #endif
  52.  
  53. #include "RawKey.h"
  54. #include "Keyboard.h"
  55.  
  56. #define NUMBOMB 5
  57. #define NUMALIEN 20
  58.  
  59. Palette gamepal;
  60. animList explode;
  61. StarField starfield;
  62. Player ship;
  63. Sprite bomb[NUMBOMB],alien[NUMALIEN],multiple,logo, checkerboard,life[NUMLIVES];
  64. byte *vscreen;
  65.  
  66. Sample snd[NUM_SAMPLES];
  67. bool aliendead[NUMALIEN];
  68. bool option_effects=true;
  69. int ticks, aliens_left, level;
  70. int sred[256], sgreen[256], sblue[256];
  71. Popgun pop(&ship);
  72.  
  73. /////////////////////////////////////////////////////////////////////////////
  74. // Sets up the title screen
  75. /////////////////////////////////////////////////////////////////////////////
  76. void
  77. primetitle(void)
  78. {
  79.     cls(vscreen,0);
  80.     logo.setPos((logo.getScreenWidth()-logo.getWidth())/2,0);
  81.     logo.setVisible(true);
  82.     multiple.setPos(150,180);
  83.     multiple.setVisible(true);
  84. }
  85.  
  86. ////////////////////////////////////////////////////////////////////////////
  87. // Sets the control to joystick if possible, or keyboard otherwise.
  88. ////////////////////////////////////////////////////////////////////////////
  89. #ifdef JOYSTICK
  90. Joystick joystick;
  91. #endif
  92.  
  93. Control *set_joystick(Control *c)
  94. {
  95.     if (c!=0 && c->getRaw()==true)
  96.         delete c;
  97. #ifdef JOYSTICK
  98.     c=&joystick;
  99.     if (c->getOkay()==false)
  100.     {
  101.         c=new RawKey;
  102.         cerr << "Using Raw Keyboard\n";
  103.     }
  104. #else
  105.     c=new RawKey;
  106.     cerr << "Using Raw Keyboard\n";
  107. #endif
  108.     if(c->getOkay()==false)
  109.     {
  110.         cerr << "No controls available!" << endl; 
  111.     }
  112.     return c;
  113. }
  114.  
  115. Control* set_keyboard(Control *c)
  116. {
  117.     if (c!=0 && c->getRaw()==true)
  118.         delete c;
  119.     c=new RawKey;
  120.     return c;
  121. }
  122.  
  123. /////////////////////////////////////////////////////////////////////////////
  124. // Main entry point - Also contains menu code (may change that!)
  125. /////////////////////////////////////////////////////////////////////////////
  126. int
  127. main(void)
  128. {
  129.     void initialise(void);
  130.     void getsprites(void);
  131.     void maingame( void);
  132.     int choice=0;
  133.  
  134.     initialise();
  135.     cerr << "inited" << endl;
  136.  
  137.     // Set the start up control 
  138.     Control *control=0;
  139.     control=set_joystick(control);
  140.     ship.setControl(control);
  141.  
  142.     cerr << "set slot" << endl;
  143.     ship.setWeapon(&pop,FRONT);
  144.     starfield.setGraphMem(vscreen);
  145.     
  146.     getsprites();
  147.     cerr << "Got sprites" << endl;
  148.     gamepal.allocate(255, 30, 0, 0 );
  149.     gamepal.allocate(0, 0, 0, 0 );
  150.  
  151.     char* menu1[]={"New Game", "Options","Load Game", "Save Game", "Quit"};
  152.     char* menu2[]={"Sound","Control"};
  153.     char* menu3[]={"On","Off"};
  154.     char* menu4[]={"Keyboard","Joystick"};
  155.     char** mtext[]={menu1,menu2,menu3,menu4};
  156.     int mlen[]={5,2,2,2};
  157.     int cmenu=0, oldcmenu=0;
  158.     Menu *menu;
  159.  
  160.     menu=new Menu (mtext[cmenu],mlen[cmenu]); 
  161.     menu->setControl(control);
  162.  
  163.     use_palette(gamepal);
  164.  
  165.     primetitle();
  166.     cerr << "Starting Loop" << endl;
  167.     while(choice!=4)
  168.     {
  169.         choice=menu->choice();
  170.         switch(cmenu)
  171.         {
  172.         case 0:
  173.             switch(choice)
  174.             {    
  175.             case 0:
  176.                 logo.hideAll();
  177.                 maingame();
  178.                 primetitle();
  179.                 break;
  180.             case 1:
  181.                 cmenu=1;
  182.                 break;
  183.             default:
  184.                 break;
  185.             }
  186.             break;
  187.         case 1:
  188.             switch(choice)
  189.             {    
  190.             case 0:
  191.                 cmenu=2;
  192.                 break;
  193.             case 1:
  194.                 cmenu=3;
  195.                 break;                
  196.             }
  197.             break;
  198.         case 2:
  199.             switch(choice)
  200.             {
  201.             case 0:
  202.                 option_effects=true;
  203.                 cmenu=0;
  204.                 break;
  205.             case 1:
  206.                 option_effects=false;
  207.                 cmenu=0;
  208.                 break;
  209.             }
  210.             break;
  211.         case 3:
  212.             switch(choice)
  213.             {    
  214.             case 0:
  215.                 control=set_keyboard(control);
  216.                 cmenu=0;
  217.                 break;
  218.             case 1:
  219.                 control=set_joystick(control);
  220.                 cmenu=0;
  221.                 break;                
  222.             }
  223.             menu->setControl(control);
  224.             ship.setControl(control);
  225.             break;
  226.         default:
  227.             break;
  228.         }
  229.         //cerr << "Moving" << endl;
  230.         starfield.move();
  231.         menu->move();
  232.  
  233.         //cerr << "Moved" << endl;
  234.         starfield.getBack();
  235.         logo.getAll();
  236.         menu->getBack();
  237.         //cerr << "Got" << endl;
  238.  
  239.         starfield.paste();
  240.         logo.PasteAll();
  241.         if(oldcmenu==cmenu)
  242.             menu->paste();
  243.  
  244.         //cerr << "Displaying screen" << endl;
  245.         display(vscreen);
  246.         //cerr << "Displayed screen" << endl;
  247.  
  248.         starfield.replace();
  249.         logo.ReplaceAll();
  250.         menu->replace();
  251.         if(oldcmenu!=cmenu)
  252.         {
  253.             delete menu;
  254.             menu=new Menu (mtext[cmenu],mlen[cmenu]);
  255.             while(control->test(FIRE1))
  256.                 control->fetch(); 
  257.             menu->setControl(control);
  258.         }
  259.         oldcmenu=cmenu;
  260.     }
  261.     delete control;
  262.     exit(0);
  263. }
  264.  
  265. /////////////////////////////////////////////////////////////////////////////
  266. // Called at an exit() to tidy things up a bit
  267. /////////////////////////////////////////////////////////////////////////////
  268. void cleanup(void)
  269. {
  270.     /* Back to boring text mode! */
  271.     cls(vga_getgraphmem(),0);
  272.     for(int i=0;i<256;i++)
  273.         vga_setpalette(i, sred[i], sgreen[i], sblue[i]); 
  274.     vga_setmode(TEXT);
  275. #ifdef SOUND
  276.     Snd_restore();
  277. #endif
  278. }
  279.  
  280. /////////////////////////////////////////////////////////////////////////////
  281. // Sets up the graphics, fonts and sound
  282. /////////////////////////////////////////////////////////////////////////////
  283. void
  284. initialise (void)
  285. {
  286.     void cleanup(void);
  287.  
  288.     /* Set up screen mode */
  289.     vga_init();
  290.     vga_setmode(G320x200x256);
  291.  
  292.     /* Save palette */
  293.     for(int i=0;i<256;i++)
  294.         vga_getpalette(i, &sred[i], &sgreen[i], &sblue[i]); 
  295.  
  296.     /* Get font */
  297.     fontinit();
  298.  
  299. #ifdef SOUND
  300.     /* First, we load our raw samples into memory */
  301.     Snd_loadRawSample( "sfx/zap.raw", &snd[SND_POPGUN] );
  302.        Snd_loadRawSample( "sfx/explode.raw", &snd[SND_EXPLODE] );
  303.        Snd_loadRawSample( "sfx/harp.snd", &snd[SND_HARP] );
  304.  
  305.        /* now init the soundIt library */
  306.     if (Snd_init( NUM_SAMPLES, snd, SAMPLE_RATE, NUM_CHANNELS, "/dev/dsp" )==EXIT_FAILURE)
  307.         {
  308.             printf("Can't init soundIt library. yech..\n");
  309.             exit(0);
  310.         }
  311. #endif
  312.     /* Try to organise a tidy cleanup */
  313.     atexit(cleanup);
  314. }
  315.  
  316. /////////////////////////////////////////////////////////////////////////////
  317. // Cuts out the sprite images contained in the invsprit.gif file
  318. /////////////////////////////////////////////////////////////////////////////
  319. void
  320. getsprites (void)
  321. {
  322.     Gif gif;
  323.     Palette gifpal;
  324.     int i;
  325.  
  326.     /* Load picture containing sprites */
  327.     FILE *fp=alopen("gfx/invsprit.gif","rb");    
  328.     gif.Load(fp);
  329.     gifpal.scan(gif.getPtr(), gif.getWidth()*gif.getHeight());
  330.     gif.SetPalette(gifpal);
  331.     gamepal.remap(gif.getPtr(), gif.getWidth()*gif.getHeight() , gifpal);
  332.     
  333.     ship.setGraphMem(gif.getPtr());        
  334.  
  335.     ship.Cut(8,16,4,8,POPGUNSLOT);
  336.     ship.Cut(0,16,8,16,PLASMAGUNSLOT);
  337.     pop.setSlot(POPGUNSLOT);
  338.  
  339.     animList manim;
  340.     for(i=0;i<16;i++)
  341.     {
  342.         multiple.Cut(24+i*8,16,8,8,MULTSLOT+i);
  343.         manim.append(animElt(MULTSLOT+i,2));
  344.     }
  345.     manim.append(animElt(LOOPANIM,0));
  346.     multiple.loadFilm(manim);
  347.     multiple.setAnim(true);
  348.  
  349.     /* Cut the sprites */
  350.     life[0].Cut(0,80,8,8,LIFESLOT);
  351.     for(i=1;i<NUMLIVES;i++)
  352.         life[i]=life[0];
  353.  
  354.     logo.Cut(0,88,88,24,LOGOSLOT);
  355.  
  356.     ship.Cut(0,0,16,16,SHIPSLOT);
  357.     ship.Cut(16,0,16,16,SHIPSLOT+1);
  358.     ship.Cut(32,0,16,16,SHIPSLOT+2);
  359.     ship.Cut(48,0,16,16,SHIPSLOT+3);
  360.     ship.Cut(64,0,16,16,SHIPSLOT+4);
  361.     ship.Cut(80,0,16,16,SHIPSLOT+5);
  362.  
  363.     bomb[0].Cut(16,16,8,8,BOMBSLOT);
  364.     for(i=1;i<NUMBOMB;i++)
  365.         bomb[i]=bomb[0];
  366.  
  367.     alien[0].Cut(0,32,16,16,EXPLODESLOT);
  368.     alien[0].Cut(16,32,16,16,EXPLODESLOT+1);    
  369.     alien[0].Cut(32,32,16,16,EXPLODESLOT+2);    
  370.     explode=animElt(EXPLODESLOT,2)+
  371.         animElt(EXPLODESLOT+1,2)+animElt(EXPLODESLOT+2,1)+animElt(VANISHANIM,0);
  372.  
  373.     alien[0].Cut(48,48,16,16,ALIENSLOT);
  374.     alien[0].Cut(48,48,16,16,ALIENSLOT+1);
  375.     alien[0].Cut(48,48,16,16,ALIENSLOT+2);
  376.  
  377.     vscreen=new byte [65535];
  378.     ship.setGraphMem(vscreen);    
  379. }
  380.  
  381. /////////////////////////////////////////////////////////////////////////////
  382. // Puts the sprites in place at the start of a level
  383. /////////////////////////////////////////////////////////////////////////////
  384. void primesprites(void)
  385. {
  386.     animList aan=animElt(ALIENSLOT,5) + animElt(ALIENSLOT+1,5)+ animElt(ALIENSLOT+2,5) + animElt(LOOPANIM,0);  
  387.     alien[0].loadFilm(aan);
  388.     alien[0].setAnim(true);
  389.  
  390.     for(int i=0;i<NUMALIEN;i++)
  391.     {
  392.         alien[i]=alien[0];
  393.         aliendead[i]=false;
  394.     }
  395.  
  396.     ship.setPos(152,182);
  397.  
  398.     for(i=0;i<ship.getLives();i++)
  399.     {
  400.         life[i].setPos(SCREENWIDTH-(i+1)*9,192);
  401.     }
  402.  
  403.     i=0;
  404.     for(int y=0; y<NUMALIEN/5; y++)
  405.     {
  406.         for(int x=0; x<NUMALIEN/4; x++)
  407.         {
  408.             alien[i].setPos(x*40+100,y*30+20);
  409.             alien[i].setDelta(-1,0);
  410.             i++;
  411.         }
  412.     }
  413.     ship.setVisible(true);    
  414.     for(i=0;i<ship.getLives();i++)
  415.         life[i].setVisible(true);
  416.     for(i=0;i<NUMALIEN;i++)
  417.         alien[i].setVisible(true);
  418. }
  419.  
  420. /////////////////////////////////////////////////////////////////////////////
  421. // Has the player collided with and alien?
  422. /////////////////////////////////////////////////////////////////////////////
  423. bool collide(void)
  424. {
  425.     for(int a=0; a<NUMALIEN; a++)
  426.     {
  427.         if( alien[a].getVisible()==true && ship.collide(alien[a]) )
  428.             return true;
  429.     }        
  430.     return false;
  431. }
  432.  
  433. /////////////////////////////////////////////////////////////////////////////
  434. // Checks if the player has shot anything.
  435. /////////////////////////////////////////////////////////////////////////////
  436. void checklaser(void)
  437. {
  438.     for(int a=0; a<NUMALIEN; a++)
  439.     {
  440.         if( !aliendead[a] && ship.hit(alien[a]) )
  441.         {
  442.             aliens_left--;
  443.             alien[a].loadFilm(explode);
  444.             alien[a].setAnim(true);
  445.             aliendead[a]=true;
  446.             if(option_effects)
  447.                 Snd_effect(SND_EXPLODE,CHAN_EXPLODE);
  448.             ship.addScore(10);
  449.         }
  450.     }
  451. }
  452.  
  453. /////////////////////////////////////////////////////////////////////////////
  454. // Checks if the aliens weapons have hit the player.
  455. /////////////////////////////////////////////////////////////////////////////
  456. void checkbomb(void)
  457. {
  458.     for(int i=0;i<NUMBOMB;i++)
  459.     {
  460.         if(bomb[i].getVisible() && bomb[i].collide(ship))
  461.         {
  462.             ship.explode();
  463.             int oldlife=ship.getLives();
  464.             ship.subEnergy(20);    
  465.             if(ship.getLives()<oldlife);
  466.                 life[oldlife-1].disappear();
  467.             bomb[i].disappear();
  468.         }
  469.     }
  470. }
  471.  
  472. /////////////////////////////////////////////////////////////////////////////
  473. // Moves the aliens bombs.
  474. /////////////////////////////////////////////////////////////////////////////
  475. void movebomb(void)
  476. {
  477.     for(int i=0;i<NUMBOMB;i++)
  478.     {
  479.         bomb[i].move();
  480.         if(bomb[i].getYp()> SCREENHEIGHT-bomb[i].getHeight() )
  481.             bomb[i].disappear();
  482.     }
  483. }
  484.  
  485. /////////////////////////////////////////////////////////////////////////////
  486. // Launches and alien weapon
  487. /////////////////////////////////////////////////////////////////////////////
  488. void 
  489. alienfire( const Sprite& a)
  490. {
  491.     static int last;
  492.  
  493.     if(ticks-last>8)
  494.     {
  495.     int i=0;
  496.     while(bomb[i].getVisible() && i<NUMBOMB)
  497.         i++;
  498.     if(bomb[i].getVisible() || i>=NUMBOMB)
  499.         return;
  500.     bomb[i].setDelta(0, 1+level/2);
  501.     bomb[i].setPos(a.getXp()+4, a.getYp()+16);
  502.     bomb[i].appear();
  503.     last=ticks;
  504.     }
  505. }
  506.  
  507. /////////////////////////////////////////////////////////////////////////////
  508. // Moves the aliens.
  509. /////////////////////////////////////////////////////////////////////////////
  510. void movealiens(void)
  511. {
  512.     int left=0, right=0, curalien;
  513.     
  514.     /* move the aliens */    
  515.     for(curalien=0; curalien<NUMALIEN; curalien++)
  516.     {
  517.         if(alien[curalien].getVisible())
  518.         {    
  519.             if( alien[curalien].getXp() <= 0 )
  520.                 right=1;
  521.             if( alien[curalien].getXp() > 303 )
  522.                 left=1;
  523.         }
  524.     }
  525.  
  526.     if(left)
  527.     {
  528.         for(curalien=0; curalien<NUMALIEN; curalien++)
  529.             {
  530.             alien[curalien].setDelta(-1,0);
  531.             alien[curalien].move(0,1+level);
  532.             }
  533.     }
  534.  
  535.     if(right)
  536.     {
  537.         for(curalien=0; curalien<NUMALIEN; curalien++)
  538.         {
  539.             alien[curalien].setDelta(1,0);
  540.             alien[curalien].move(0,1+level);
  541.         }
  542.     }
  543.  
  544.     for(curalien=0; curalien<NUMALIEN; curalien++)
  545.     {
  546.         alien[curalien].move();
  547.         if(!aliendead[curalien] && alien[curalien].getVisible() && 
  548.             (alien[curalien].getXp()==ship.getXp() || rnd(100)>80) )
  549.             alienfire(alien[curalien]);
  550.     }
  551. }
  552.  
  553. /////////////////////////////////////////////////////////////////////////////
  554. // Does the scrolling text ( Level one etc )
  555. /////////////////////////////////////////////////////////////////////////////
  556. void scrolly( char *message)
  557. {
  558.     int x;
  559.     cls(vscreen,0);
  560.     for(x=0;x<SCREENWIDTH-strlen(message)*8;x+=2)
  561.     {
  562.         print(message,vscreen,x,SCREENHEIGHT/2-4);
  563.         waitvbl();
  564.         screencopy(vscreen,graph_mem);
  565.     }
  566.     cls(vscreen,0);
  567. }
  568.  
  569. void levelintro(int l)
  570. {
  571.     char buffer[80];
  572.     sprintf(buffer," Level %d",l);
  573.     scrolly(buffer);
  574. }
  575.  
  576. /////////////////////////////////////////////////////////////////////////////
  577. // Runs the high level game, ie sets up each level
  578. /////////////////////////////////////////////////////////////////////////////
  579. void maingame(void)
  580. {
  581.     void gameinit(void);
  582.     void game(void);
  583.  
  584.     level=1;
  585.     gameinit();
  586.     while(level<11 && ship.getLives()>0)
  587.     {
  588.         cls(vscreen,0);
  589.         starfield.getBack();
  590.         ship.hideAll();
  591.         primesprites();
  592.         if(option_effects)
  593.             Snd_effect(SND_HARP,CHAN_PLAYER);
  594.         levelintro(level);
  595.         for(int i=0;i<NUMALIEN;i++)
  596.             aliendead[i]=false;
  597.         game();
  598.         level++;
  599.     }
  600.     if(ship.getLives()==0)
  601.         scrolly(" You're dead, loser!.");
  602.     else if(level==11 && ship.getLives()>0)
  603.         scrolly(" You Won! Now code some more.");
  604.     ship.hideAll();
  605.     cls(vscreen,0);
  606. }
  607.  
  608. void gameinit(void)
  609. {
  610.     ship.setScore(0);
  611.     ship.setLives(3);
  612.     level=1;
  613. }
  614.  
  615. /////////////////////////////////////////////////////////////////////////////
  616. // The main game loop is in here.
  617. /////////////////////////////////////////////////////////////////////////////
  618. void game(void)
  619. {
  620.     int key=0;
  621.     char buffer[80];
  622.  
  623.     aliens_left=NUMALIEN;
  624.     Block panel;
  625.     panel.cut(0,192,80,8);
  626.  
  627.     while(key!='q')
  628.     {
  629.         /* move the player */
  630.         ship.control();
  631.  
  632.         /* move the aliens */
  633.         if(ticks%2) movealiens();
  634.  
  635.         /*move the bullets*/    
  636.         movebomb();
  637.  
  638.         /*check bullets*/
  639.         checklaser();
  640.         checkbomb();
  641.  
  642.         /*Check for a win*/
  643.         if(aliens_left<=0)
  644.         {
  645.              key='q';
  646.         }
  647.  
  648.         /*check if the player is dead*/
  649.  
  650.         if(collide() || ship.getLives()==0)
  651.             return;
  652.  
  653.         /*************** Screen is updated here *********************/    
  654.         /* First replace the background */
  655.         /* Then get the new background */
  656.         ship.getAll();
  657.         starfield.getBack();
  658.         panel.reCut(0,192);
  659.  
  660.         /* Then paste on the graphics */
  661.         starfield.paste();
  662.         ship.PasteAll();   
  663.         sprintf(buffer,"%d",ship.getScore());
  664.         printor(buffer, vscreen,0,192);
  665.  
  666.         display(vscreen);
  667.  
  668.         ship.ReplaceAll();
  669.         starfield.replace();
  670.         panel.paste(0,192);
  671.  
  672.         starfield.move();
  673.  
  674.         /*************** Count game ticks **************************/
  675.         ticks++;
  676.     }
  677. }
  678.